package com.atguigu.gmall.mq.receiver;

import com.atguigu.gmall.mq.config.DeadLetterMqConfig;
import com.atguigu.gmall.mq.config.DelayedMqConfig;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author mgx
 * @create 2024-09-03 21:23
 * @Description
 */
@Component
@Slf4j
public class DeadLetterReceiver {

    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 实现幂等性的思路：
     * 1. 是否接收消息添加标记
     *      redis setNx
     * 2. 如果redis中存在了，一定是已经消费了嘛？
     *      消费 1  未消费 0 -- value
     * @param msg
     * @param message
     * @param channel
     */
    @SneakyThrows
    @RabbitListener(queues = DelayedMqConfig.queue_delay_1)
    public void getDelayedLetter(String msg, Message message, Channel channel) {
        String msgKey = "delay:" + msg;
        Boolean result = redisTemplate.opsForValue().setIfAbsent(msgKey, "0", 10, TimeUnit.MINUTES);
        if(!result) {
            // 标记失败-代表已经有相同的消息
            // 获取是否消费
            String isConsume = (String) redisTemplate.opsForValue().get(msgKey);
            if("1".equals(isConsume)) {
                // 已经消费过了
                // 确认消息
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }else {
                // 未消费
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                System.out.println("收到的消息: --> " + msg);
                System.out.println(simpleDateFormat.format(new Date()));
                // 修改redis中的值为已消费
                redisTemplate.opsForValue().set(msgKey, "1");
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }
        }else {
            // 标记成功-第一次消费
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("收到的消息: --> " + msg);
            System.out.println(simpleDateFormat.format(new Date()));
            // 修改redis中的值为已消费
            redisTemplate.opsForValue().set(msgKey, "1");
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

        }
    }


    @SneakyThrows
    @RabbitListener(queues = DeadLetterMqConfig.queue_dead_2)
    public void getDeadLetter(String msg, Message message, Channel channel) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("收到的消息: --> " + msg);
        System.out.println(simpleDateFormat.format(new Date()));
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

    // 没保证消费幂等性的版本
    /*@SneakyThrows
    @RabbitListener(queues = DelayedMqConfig.queue_delay_1)
    public void getDelayedLetter(String msg, Message message, Channel channel) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("收到的消息: --> " + msg);
        System.out.println(simpleDateFormat.format(new Date()));
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }*/
}
